<template>
  <el-card>
    <!-- 
      lazy 启动数据懒加载
      load 懒加载时触发的函数
      tree-props table表格中data数据中的对象字段
      row-key="id" 必须写 table遍历元素的每个元素的key属性值
     -->
    <el-table
      :data="categoryList"
      border
      lazy
      :load="load"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      :row-key="getRowKey"
      ref="tableRef">
      <el-table-column label="分类ID" prop="id" width="150" align="center" />
      <el-table-column label="分类名称" prop="name" />

      <el-table-column width="250" align="center">
        <template #header>
          <el-input
            placeholder="按Enter键添加一级分类"
            v-model="categoryName"
            @keyup.enter="addCategory1" />
        </template>
        <template v-slot="{ row }">
          <el-button
            type="primary"
            :icon="Plus"
            size="small"
            :disabled="row.level === 3"
            @click="showAddCategory(row)"></el-button>
          <el-button
            type="warning"
            :icon="Edit"
            size="small"
            @click="showUpdateCategory(row)"></el-button>
          <el-button type="danger" :icon="Delete" size="small"></el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-dialog
      v-model="dialogTableVisible"
      :title="`${isUpdateCategory ? '更新' : '添加'}${
        category.level === 1 ? '二级' : '三级'
      }分类`">
      <el-form>
        <el-form-item label="分类名称">
          <el-input
            placeholder="请输入分类名称"
            v-model="updatedCategory.name"
            v-if="isUpdateCategory" />
          <el-input
            placeholder="请输入分类名称"
            v-model="categoryName"
            v-else />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="cancel">取消</el-button>
        <el-button
          type="primary"
          @click="updateCategory"
          v-if="isUpdateCategory"
          >确认</el-button
        >
        <el-button type="primary" @click="addCategory" v-else>确认</el-button>
      </template>
    </el-dialog>
  </el-card>
</template>

<script lang="ts">
export default {
  name: "JCategory",
};
</script>

<script lang="ts" setup>
import { ref, onMounted } from "vue";
import { Delete, Edit, Plus } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";

import {
  getCategory1ListApi,
  getCategory2ListApi,
  getCategory3ListApi,
  addCategory1Api,
  addCategory2Api,
  addCategory3Api,
  updateCategory1Api,
  updateCategory2Api,
  updateCategory3Api,
} from "@/api/product/category";
import type {
  CategoryList,
  CategoryItem,
} from "@/api/product/model/categoryModel";

const categoryList = ref<CategoryList>([]);

// 封装获取一级分类
const getCategory1List = async () => {
  const res = await getCategory1ListApi();
  categoryList.value = res.map((category) => {
    return {
      ...category,
      hasChildren: true,
      level: 1,
    };
  });
};

// 挂载就获取一级分类
onMounted(getCategory1List);

// 树桩懒加载
const load = async (
  row: CategoryItem,
  treeNode: unknown,
  resolve: (date: CategoryList) => void
) => {
  // 点击触发level函数，加载二级分类和三级分类
  if (row.level === 1) {
    const res = await getCategory2ListApi(row.id);
    // resolve 是个函数 必须调用，调用就会给当前节点Children 添加值
    resolve(
      res.map((category) => {
        return {
          ...category,
          // 是否展示树桩
          hasChildren: true,
          level: 2,
        };
      })
    );
  }
  // 根据二级分类标识  获取三级分类数据
  if (row.level === 2) {
    const res = await getCategory3ListApi(row.id);
    resolve(
      res.map((category) => {
        return {
          ...category,
          level: 3,
        };
      })
    );
  }
};

// 文档上参数就是row
const getRowKey = (row: CategoryItem) => {
  return row.level + "-" + row.id;
};

// 收集用户输入
const categoryName = ref("");

// 添加一级分类
const addCategory1 = async () => {
  if (!categoryName.value) return;
  await addCategory1Api(categoryName.value);
  ElMessage.success("添加一级分类成功");
  getCategory1List();
  categoryName.value = "";
};

// 模态框是否展示
const dialogTableVisible = ref(false);
const tableRef = ref();
const category = ref<CategoryItem>({
  id: 0,
  name: "",
});

// 隐藏添加框
const cancel = () => {
  dialogTableVisible.value = false;
  categoryName.value = "";
};

// 添加分类
const addCategory = async () => {
  if (!categoryName.value) return;
  if (category.value.level === 1) {
    await addCategory2Api(categoryName.value, category.value.id);
  } else if (category.value.level === 2) {
    await addCategory3Api(categoryName.value, category.value.id);
  }
  // 找到对应的数据，将loaded改成false，代表这个数据没有被加载
  tableRef.value.store.states.treeData.value[
    `${category.value.level}-${category.value.id}`
  ].loaded = false;
  // 重新触发load，加载渲染相应的子节点
  tableRef.value.store.loadOrToggle(category.value);

  ElMessage.success(
    `添加${category.value.level === 1 ? "二级" : "三级"}分类成功`
  );
  cancel();
};

// 显示添加框
const showAddCategory = (row: CategoryItem) => {
  isUpdateCategory.value = false;
  dialogTableVisible.value = true;
  category.value = row;
};

const isUpdateCategory = ref(false);
const updatedCategory = ref<CategoryItem>({
  id: 0,
  name: "",
});

// 显示更新分类
const showUpdateCategory = (row: CategoryItem) => {
  isUpdateCategory.value = true;
  dialogTableVisible.value = true;
  category.value = row;
  updatedCategory.value = { ...row };
};

// 更新逻辑
const updateCategory = async () => {
  if (!category.value.name) return;
  if (category.value.level === 1) {
    await updateCategory1Api(category.value.id, categoryName.value);
  } else if (category.value.level === 2) {
    await updateCategory2Api(category.value.id, categoryName.value);
  } else {
    await updateCategory3Api(category.value.id, categoryName.value);
  }

  category.value.name = updatedCategory.value.name;
  ElMessage.success("更新分类成功");
  cancel();
};
</script>

<style scoped></style>
